<template>
  <div class="date_progress" :style="{ height: height + 'px' }">
    <div class="progress_bar">
      <div class="bg" :style="{ height: height + 'px' }"></div>
      <div class="process_content">
        <div
          v-for="(item, i) in cellList"
          :key="i"
          class="process_cell"
          :style="{
            height: oneCellHeight + 'px',
          }"
          :class="{
            active: activeWeekCount === item.count,
          }"
          @click="clickCellMethod(item)"
        >
          <el-tooltip :content="`第${item.count}周`" placement="right">
            <span
              class="week_count"
              :class="{ active: activeWeekCount === item.count }"
            >
              {{ item.count }}
            </span>
          </el-tooltip>
        </div>
      </div>
    </div>
    <div
      :style="{
        height: oneCellHeight + 'px',
        bottom: oneCellHeight * (activeWeekCount - 1) + 'px',
      }"
      class="active_cell"
    ></div>
  </div>
</template>

<script>
import { ref, getCurrentInstance, watch } from "vue";
import { ElMessage } from "element-plus";

export default {
  name: "DateProgress",
  props: {
    height: {
      type: Number,
      default: 547,
    },
    year: {
      type: Number,
      default: 0,
    },
  },
  setup(props, context) {
    const { proxy } = getCurrentInstance();
    const $moment = proxy.$moment;

    // 计算当前年份的总周数
    let totalWeekCount = $moment().weeksInYear();

    // 一个周元素 cell 所占高度
    const oneCellHeight = ref(0);

    // 周数数组
    const cellList = ref([]);

    // 初始化-计算当前时间是当前年的第几周（一开始就已经确定的值）
    const currentWeekCount = $moment().weeks();

    // 当前选中的周数（可变值）默认选中当前时间的周数
    const activeWeekCount = ref(currentWeekCount);

    // 监听年份变化，刷新总周数，
    watch(
      () => props.year,
      (newVal, oldVal) => {
        totalWeekCount = $moment(newVal).weeksInYear();
        if (newVal > oldVal) {
          // 前进到下一年的第一周
          activeWeekCount.value = 1;
          if (newVal < $moment().weekYear()) {
            cellList.value = getCellList(totalWeekCount);
          } else {
            cellList.value = getCellList(currentWeekCount);
          }
        } else {
          // 后退到上一年的最后一周
          activeWeekCount.value = totalWeekCount;
          cellList.value = getCellList(totalWeekCount);
        }
      }
    );

    // 监听整个高度变化，计算一个周元素 cell 所占高度
    watch(
      () => props.height,
      (val) => {
        oneCellHeight.value = val / totalWeekCount;
      }
    );

    // 计算要显示的周数数组
    const getCellList = (weekCount) => {
      const list = [];
      if (weekCount > 0) {
        for (let i = 0; i < weekCount; i++) {
          list.push({ count: weekCount - i });
        }
      }
      return list;
    };

    const clickCellMethod = (item) => {
      activeWeekCount.value = item.count;
    };

    /**
     * 切换当前选中的周数
     * type => 1 : 前进一周（周数加1）；-1 : 后退一周（周数减1）
     */
    const goWeekCountMethod = (type) => {
      if (type === 1) {
        if (props.year < $moment().weekYear()) {
          if (activeWeekCount.value < totalWeekCount) {
            activeWeekCount.value++;
          } else {
            // 跨年了，去到下一年的第一周
            context.emit("changeYear", type);
          }
        } else {
          // 只允许小于当前时间的周数
          if (activeWeekCount.value < currentWeekCount) {
            activeWeekCount.value++;
          } else {
            ElMessage.warning("最大只能到当前周哦~");
          }
        }
      } else if (type === -1) {
        if (activeWeekCount.value > 1) {
          activeWeekCount.value--;
        } else {
          // 跨年了，去到上一年的最后一周
          context.emit("changeYear", type);
        }
      }
    };

    // 监听当前选中的周数，返回星期一到星期天的日期
    watch(
      () => activeWeekCount.value,
      (val) => {
        // console.log(`activeWeekCount => ${val}`);
        // 返回周数的星期的日期
        const firstDateInWeek = $moment(props.year, "YYYY")
          .week(val)
          .weekday(0)
          .format("YYYY-MM-DD");
        // 触发事件，把星期一的日期传递给日期tab
        // console.log("把星期一的日期传递给日期tab ==>", firstDateInWeek);
        context.emit("changeWeek", firstDateInWeek);
      }
    );

    // -------------------- 初始化 --------------------------
    cellList.value = getCellList(currentWeekCount);

    return {
      cellList,
      activeWeekCount,
      oneCellHeight,
      clickCellMethod,
      goWeekCountMethod,
    };
  },
};
</script>

<style lang="less" scoped>
.date_progress {
  position: absolute;
  bottom: 20px;
  left: 8px;
  z-index: 10;
  width: 6px;
  transition: width 0.2s linear;
  &:hover {
    width: 20px;
    .progress_bar {
      border-radius: 10px 10px 0 0;
    }
    .week_count {
      display: block;
    }
    .active_cell {
      display: none;
    }
  }

  .progress_bar {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    transition: border-radius 0.2s linear;
    border-radius: 3px 3px 0 0;
    overflow: hidden;

    .bg {
      position: absolute;
      bottom: 0;
      left: 0;
      width: 100%;
      background-image: linear-gradient(
        to top,
        #67c23a 33%,
        #e6a23c 66%,
        #f56c6c
      );
    }

    .process_content {
      position: relative;
      width: 100%;
      z-index: 10;
      .process_cell {
        width: 100%;
        cursor: pointer;
        transition: all 0.2s linear;
        display: flex;
        align-items: center;
        justify-content: center;
        &:hover {
          // background-color: rgba(0,0,0,0.1);
          transform: scale(1.3);
        }
        &.active {
          // border: 1px solid #ccc;
        }
      }
    }
  }

  .active_cell {
    position: absolute;
    bottom: 0;
    left: -2px;
    width: 6px;
    // background: #409EFF;
    border: 2px solid #409eff;
    z-index: 10;
  }

  .week_count {
    font-size: 12px;
    color: #fff;
    display: none;
    &.active {
      color: #666;
    }
  }
}

@keyframes tab_active_ani {
  0% {
    transform: perspective(300px) skew(0, 0) rotate3d(1, 0, 0, 270deg);
    opacity: 0;
  }
  100% {
    transform: perspective(300px) skew(-5deg, 0) rotate3d(1, 0, 0, 360deg);
    opacity: 1;
  }
}
</style>
